<!--

    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.

-->

<html>
<head>
<title>Options API</title>
<link rel="Stylesheet" href="../../../../prose.css" type="text/css" title="NetBeans Open APIs Style">
</head>
<body>

<p class="overviewlink"><a href="../../../../overview-summary.html">Overview</a></p>

<h1>Javadoc</h1>

Please see

<a href="../package-summary.html"><code>org.openide.options</code></a>

for the relevant classes.

<h1>Contents</h1>

<ul>

<li><a href="#intro">What are Options?</a>

<li><a href="#make-opt">Creating a System Option</a>
<ul>
<li><a href="#make-singleton">Creating the singleton class</a>
<li><a href="#props">Providing getters and setters for properties</a>
<li><a href="#beaninfo">Providing more advanced bean info</a>
<li><a href="#cluster">Making an option cluster</a>
<li><a href="#veto">Vetoable options</a>
<li><a href="#module">Option installation</a>
</ul>

<li><a href="#access">Accessing Existing System Options</a>

<li><a href="#diagram">UML class diagram</a>

</ul>

<h1>Options API</h1>

<h2><a name="intro">What are Options?</a></h2>

NetBeans <em>system options</em> are groupings of user-settable
properties which a module author desires to make available
for two purposes: allowing a user to view and modify the existing
settings pertaining to a module; and allowing NetBeans to store these
options to disk when it needs to, in a centralized operation (so that
it is easy for an administrator to see where all NetBeans settings reside).

<p>Options installed into the system are automatically saved to disk
when changed.

<h2><a name="make-opt">Creating a System Option</a></h2>

Creating a new system option is generally quite easy. In simple cases,
the entire source for a system option can fit on one page.

<h3><a name="make-singleton">Creating the singleton class</a></h3>

First you must subclass

<a href="../SystemOption.html"><code>SystemOption</code></a>

(or one of its subclasses). The option class should be a
<em>singleton</em>, i.e. it does not need any per-instance state; all
variable members can be static. You should create one static member
(typically) for each property that you want to provide, and also give
it a sensible default value. Regardless, the option should have a
default constructor so that it can be instantiated.

<p><em>Note</em> that all property values must be serializable!

<p>Conventionally, option class names are based on the module
providing them, and ought to end in <code>Settings</code>: e.g.,
<code>MyModuleSettings</code>. This does not affect display, however;
every option must implement

<a href="../SystemOption.html#displayName--"><code>SystemOption.displayName()</code></a>

to provide a reasonable name to present to users in the Control Panel.

<p class="nonnormative">If it makes other code in the module more
convenient, you may want to have a static "get the default" method in
the option which returns the singleton of the option - but this is in
no way required. Keeping the singleton as a static variable in any
class is discouraged as it forces the system to load the stored
option's settings as soon as that class is resolved, when otherwise
loading the settings might never have been required.</p>

<h3><a name="props">Providing getters and setters for properties</a></h3>

First of all, it is a good idea to make static variables containing
the event name of each property you are exposing, e.g.:

<pre>
/** Property name for foreground color of my module, of type {@link Color}. */
public static final String PROPERTY_FOREGROUND = "foreground";
</pre>

Doing so makes it possible for other components to listen to
changes in the option object.

<p>Then, a <em>nonstatic</em> getter/setter pair should be provided
for each property, which should update the <em>static</em> class-wide
state. For this purpose, it is possible to manually keep static variables
with the current state, and manually fire property change events; but
it is more convenient to use the automatically-managed state provided by

<a href="@org-openide-util-ui@/org/openide/util/SharedClassObject.html"><code>SharedClassObject</code></a>:

<pre>
public Color getForeground () {
  // Retrieves from class-wide state:
  return (Color) <a href="@org-openide-util-ui@/org/openide/util/SharedClassObject.html#getProperty-java.lang.Object-">getProperty</a> (PROPERTY_FOREGROUND);
}
public void setForeground (Color fg) {
  // make sure it is sane...
  if (fg == null) throw new NullPointerException ();
  // Stores in class-wide state and fires property changes if needed:
  <a href="@org-openide-util-ui@/org/openide/util/SharedClassObject.html#putProperty-java.lang.String-java.lang.Object-boolean-">putProperty</a> (PROPERTY_FOREGROUND, fg, true);
}
</pre>

Note that <code>getProperty</code> and <code>putProperty</code> automatically
provide sufficient synchronization for the option as well.

<p><strong>Note:</strong> when using these methods, your getters and setters will not
be called during project save and restore; instead, the actual property value you
stored will be serialized and deserialized. This is convenient for some purposes, e.g.
you may make a property of declared type

<a href="@org-openide-util-ui@/org/openide/ServiceType.html"><code>ServiceType</code></a>

(and have a pleasant default property editor) while actually storing the correct

<a href="@org-openide-util-ui@/org/openide/ServiceType.Handle.html"><code>ServiceType.Handle</code></a>

in the project. <strong>However</strong>, it can be dangerous in some cases, e.g.
if you are associating some sort of runtime service configuration with the property
which you need the setter to immediately modify: your setter will not be used at project
restore time. To make sure the setter is used, just manually store the property without
using <code>putProperty</code>.

<h3><a name="beaninfo">Providing more advanced bean info</a></h3>

<p>By default,

<a href="@JDK@/java/beans/Introspector.html">JavaBeans introspection</a>

is used to find the properties associated with a system option, and to
read and write them. You may want to have more control over this
process. If so, you should create a valid

<a href="@JDK@/java/beans/BeanInfo.html"><code>BeanInfo</code></a>

class for the option. The easiest way to do this is of course to
create a class named e.g. <code>MyModuleSettingsBeanInfo</code>.</p>

<div class="nonnormative">

<p>You might want to do this because:</p>

<ul>

<li>A property should have a short description, e.g. for display in
tool tips. If provided, such descriptions will be passed along to the
node representing the option in the Control Panel. Similarly,
individual properties may have non-default display names.

<li>A property might need a non-default property editor. You can
supply one to be used when the user is setting the value of the
property.

<li>Complex system options can take advantage of a complete customizer
component to permit the user to set many or all of the properties at
once in a more intuitive fashion.

</ul>

</div>

<p>If any property may take one of a set of possible values, then you of
course should make public constants representing these values, and
provide e.g. a tagged

<a href="@JDK@/java/beans/PropertyEditorSupport.html">property editor</a>.</p>

<h3><a name="cluster">Making an option cluster</a></h3>

If

<a href="../ContextSystemOption.html"><code>ContextSystemOption</code></a>

is used as the superclass, then there will appear in the Control Panel
one master option (possibly having some properties, possibly not) with
a group of children beneath it. Such an option should be written like
a regular one, but each child should also be a valid system option in
its own right, and they should be added to the parent (e.g. in the
parent's constructor) using

<a href="../ContextSystemOption.html#addOption-org.openide.options.SystemOption-"><code>ContextSystemOption.addOption(...)</code></a>.

<p>Such a cluster should be used for any system options for which one
property list would be unwieldy; or if it makes sense to have multiple
and separate customizer components.

<h3><a name="veto">Vetoable options</a></h3>

The superclass

<a href="../VetoSystemOption.html"><code>VetoSystemOption</code></a>

may be used for any option which desired that some or all of its
properties be constrained by listeners - i.e. if it might be impossible
for a property to be changed in a certain way when in use by a certain
other part of the module.

<p>When such a property is set, it should fire its change using

<a href="../VetoSystemOption.html#fireVetoableChange-java.lang.String-java.lang.Object-java.lang.Object-"><code>VetoSystemOption.fireVetoableChange(...)</code></a>

and be prepared to revoke the change if a veto occurs.

<h3><a name="module">Option installation</a></h3>

<p>Options can be installed via module manifest, but are better
installed as settings using the

<a href="@org-openide-util-ui@/org/openide/util/doc-files/api.html#settings">Services API</a>.</p>

<div class="nonnormative">

<h2><a name="access">Accessing Existing System Options</a></h2>

For the most part, options and their properties are only accessed
directly from within the module providing them; in this case, a new
instance or a cached default instance of the option is made available
to other classes in the module. These other components should attach
change listeners to it so that they may be kept in synch with changes
made by the user in the Control Panel.

<p>If it necessary to access some other option, you may use:

<pre>
OtherOption oo = (OtherOption) <a href="@org-openide-util-ui@/org/openide/util/SharedClassObject.html#findObject-java.lang.Class-boolean-">SystemOption.findObject</a>(OtherOption.class, true);
</pre>

You may also use this method to obtain the default instance for local use.

</div>

<div class="nonnormative">

<h2><a name="diagram">UML class diagram</a></h2>

<img src="options.gif" alt="options UML">

</div>


<hr>@FOOTER@
</body>
</html>
